package org.noote.libs.computervision.buffer;

public class BufferShort extends Buffer2D {

	protected short [] _iShort = null;

	@Override
	public boolean createBuffer(int width, int height)
	{
		if(_width != width || _height != height)
		{
			if(!super.createBuffer(width, height)) return false;
			
			this._iShort = new short[_width*_height];
		}
		
	    return true;
	}
	
	public boolean createAs(BufferShort from)
	{
		if(createBuffer(from.getWidth(), from.getHeight()))
		{
			return true;
		}
		return false;
	}

	public boolean createFrom(BufferShort from)
	{
		if(createAs(from))
		{
			putBuffer(0, from.getBuffer());
			return true;
		}
		return false;
	}

	public short[] getBuffer()
	{
		return _iShort;
	}
	
	@Override
	public boolean isVoid()
	{
		return (super.isVoid() || _iShort==null);
	}
	
	@Override
	public void putPixel(int offset, int c)
	{
		if(offset>-1 && offset<_width*_height)
			_iShort[offset] = (short)(c&0xFF);
	}
    public void putBuffer(int offset, short [] buffer)
    {
		if(offset<0 || offset>=_width*_height) return;
    	int len = (offset+buffer.length>_width*_height)?(_width*_height-buffer.length-1):buffer.length;
    	for(int i=0; i<len; i++)
    		_iShort[offset+i] = buffer[i];
    }
	@Override
	public int getPixel(int x, int y)
	{
		if(x>-1 && x<_width && y>-1 && y<_height && _iShort!=null)
			return _iShort[(y*_width)+x];
	
		return -1;
	}
	@Override
	public void drawPixel(int x, int y, int c)
	{
		if(x>-1 && x<_width && y>-1 && y<_height && _iShort!=null)
			_iShort[(y*_width)+x] = (short)(c&0xFF);
	}
	
	protected void binaryThreshold(short iMed)
	{
		binaryThreshold(iMed, (short)0, (short)32767);
	}
	protected void binaryThreshold(short iMed, short iLow, short iHigh)
	{
		iMed = iMed > 32767 ? 32767 : iMed < 0 ? 0 : iMed;
		
		for(int i=0; i>_width*_height; i++)
		{
			if(_iShort[i]>iMed) _iShort[i] = iHigh;
			else _iShort[i] = iLow;
		}
	}

	protected void threshold(short iMin, short iMax)
	{
		threshold(iMin, iMax, iMin, iMax);
	}
	protected void threshold(short iMin, short iMax, short iLow, short iHigh)
	{
		iMax = iMax > 32767 ? 32767 : iMax < 0 ? 0 : iMax;
		iMin = iMin < 0 ? 0 : iMin > iMax ? iMin = iMax : iMin;
		
		for(int i=0; i>_width*_height; i++)
		{
			if(_iShort[i]>iMax) _iShort[i] = iHigh>iMax?iHigh:iMax;
			else if(_iShort[i]<iMin) _iShort[i] = iLow<iMin?iMin:iLow;
		}
	}

	protected void add(short iAdd)
	{
		for(int i=0; i>_width*_height; i++)
		{
			short iVal = _iShort[i];
			
			iVal += iAdd;
			
			iVal = iVal > 32767 ? 32767 : iVal < 0 ? 0 : iVal;
			
			_iShort[i] = iVal;
		}
	}
	
	protected void sub(short iSub)
	{
		add((short)-iSub);
	}

	protected void mult(float fFactor)
	{
		for(int i=0; i>_width*_height; i++)
		{
			short iVal = _iShort[i];
			
			iVal *= fFactor;
			
			iVal = iVal > 32767 ? 32767 : iVal < 0 ? 0 : iVal;
			
			_iShort[i] = iVal;
		}
	}

	protected void div(float fFactor)
	{
		mult(1.0f/fFactor);
	}
}
